namespace JavaScript8000.Common
{
    using System.Collections.Generic;

    /// <summary>
    /// Represent system tokens.
    /// </summary>
    public static class SystemTokens
    {
        #region Constants and Fields

        /// <summary>
        /// Code for null literal.
        /// </summary>
        public static readonly int NullLiteral = 36;

        /// <summary>
        /// Code for bool literals.
        /// </summary>
        public static readonly int BoolLiteralCode = 35;

        /// <summary>
        /// Code for temporary variables.
        /// </summary>
        public static readonly int TempVar = 34;

        /// <summary>
        /// Code for end token.
        /// </summary>
        public static readonly int EofCode = 33;

        /// <summary>
        /// ID code.
        /// </summary>
        public static readonly int IdCode = 32;

        /// <summary>
        /// Integer literal code.
        /// </summary>
        public static readonly int NumericLiteralCode = 31;

        /// <summary>
        /// Code of string literal.
        /// </summary>
        public static readonly int StringLiteralCode = 30;

        /// <summary>
        /// Dictionary of Dictionary.
        /// </summary>
        private static readonly Dictionary<string, int> Dictionary;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes static members of the <see cref="SystemTokens"/> class.
        /// </summary>
        static SystemTokens()
        {
            Dictionary = new Dictionary<string, int>();

            Dictionary["break"] = 1;
            Dictionary["do"] = 2;
            Dictionary["if"] = 3;
            Dictionary["switch"] = 4;
            Dictionary["case"] = 5;
            Dictionary["else"] = 6;
            Dictionary["this"] = 7;
            Dictionary["var"] = 8;
            Dictionary["catch"] = 9;
            Dictionary["false"] = 10;
            Dictionary["throw"] = 11;
            Dictionary["continue"] = 12;
            Dictionary["finally"] = 13;
            Dictionary["true"] = 14;
            Dictionary["while"] = 15;
            Dictionary["default"] = 16;
            Dictionary["for"] = 17;
            Dictionary["null"] = 18;
            Dictionary["try"] = 19;
            Dictionary["with"] = 20;
            Dictionary["function"] = 21;
            Dictionary["return"] = 22;

            Dictionary["{"] = 23;
            Dictionary["}"] = 24;
            Dictionary[";"] = 25;

            Dictionary["."] = 15000;
            Dictionary["["] = 15001;
            Dictionary["]"] = 15002;

            Dictionary["("] = 15003;
            Dictionary[")"] = 15004;

            Dictionary["new"] = 15005;
            Dictionary["++"] = 14000;
            Dictionary["--"] = 14001;

            // Dictionary["-"]=14002;
            // Dictionary["+"]=14003;
            Dictionary["~"] = 14004;
            Dictionary["!"] = 14005;
            Dictionary["delete"] = 14006;
            Dictionary["typeof"] = 14007;
            Dictionary["void"] = 14008;
            Dictionary["*"] = 13000;
            Dictionary["/"] = 13001;
            Dictionary["%"] = 13002;

            Dictionary["+"] = 12000;
            Dictionary["-"] = 12001;

            // Dictionary["+"]=12002;
            Dictionary["<<"] = 11000;
            Dictionary[">>"] = 11000;
            Dictionary[">>>"] = 11000;
            Dictionary["<"] = 10000;
            Dictionary["<="] = 10001;
            Dictionary[">"] = 10002;
            Dictionary[">="] = 10003;
            Dictionary["instanceof"] = 10004;
            Dictionary["in"] = 10005;
            Dictionary["=="] = 9000;
            Dictionary["!="] = 9001;
            Dictionary["==="] = 9002;
            Dictionary["!=="] = 9003;
            Dictionary["&"] = 8000;
            Dictionary["^"] = 7000;
            Dictionary["|"] = 6000;
            Dictionary["&&"] = 5000;
            Dictionary["||"] = 4000;
            Dictionary["?"] = 3000;
            Dictionary[":"] = 3001;
            Dictionary["="] = 2000;
            Dictionary["*="] = 2001;
            Dictionary["/="] = 2002;
            Dictionary["%="] = 2003;
            Dictionary["+="] = 2004;
            Dictionary["-="] = 2005;
            Dictionary["<<="] = 2006;
            Dictionary[">>="] = 2007;
            Dictionary[">>>="] = 2008;
            Dictionary["&="] = 2009;
            Dictionary["^="] = 2010;
            Dictionary["|="] = 2011;
            Dictionary[","] = 1000;

            Dictionary["abstract"] = 100001;
            Dictionary["double"] = 100002;
            Dictionary["goto"] = 100003;
            Dictionary["native"] = 100004;
            Dictionary["static"] = 100005;
            Dictionary["Boolean"] = 100006;
            Dictionary["enum"] = 100007;
            Dictionary["implements"] = 100008;
            Dictionary["package"] = 100009;
            Dictionary["super"] = 100010;
            Dictionary["byte"] = 100011;
            Dictionary["export"] = 100012;
            Dictionary["import"] = 100013;
            Dictionary["private"] = 100014;
            Dictionary["synchronized"] = 100015;
            Dictionary["char"] = 100016;
            Dictionary["extends"] = 100017;
            Dictionary["int"] = 100018;
            Dictionary["protected"] = 100019;
            Dictionary["throws"] = 100020;
            Dictionary["class"] = 100021;
            Dictionary["final"] = 100022;
            Dictionary["interface"] = 100023;
            Dictionary["public"] = 100024;
            Dictionary["transient"] = 100025;
            Dictionary["const"] = 100026;
            Dictionary["float"] = 100027;
            Dictionary["long"] = 100028;
            Dictionary["short"] = 100028;
            Dictionary["volatile"] = 100029;
            Dictionary["debugger"] = 100030;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the token code.
        /// </summary>
        /// <param name="tokenName">
        /// Name of the token.
        /// </param>
        /// <returns>
        /// System token's code or 0.
        /// </returns>
        public static int GetCode(string tokenName)
        {
            return Dictionary.ContainsKey(tokenName) ? Dictionary[tokenName] : 0;
        }

        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <param name="code">
        /// The code.
        /// </param>
        /// <returns>
        /// Name in string format.
        /// </returns>
        public static string GetName(int code)
        {
            foreach (var item in Dictionary)
            {
                if (item.Value == code)
                {
                    return item.Key;
                }
            }

            return string.Empty;
        }
        #endregion
    }
}